"""
扑克游戏
"""


# Step 1: 定义类
#   - 数据抽象 - 属性 - 名词
#   - 行为抽象 - 方法 - 动词
# Step 2: 创建对象
# Step 3: 给对象发消息
import random
from enum import Enum, unique


# 经验: 符号常量总是优于字面常量
# 枚举类型是定义符号常量的最佳选择
# Python没有原生的枚举类型但是可以通过继承Enum来达到枚举的效果
@unique
class Direction(Enum):
    """方向"""
    UP = 0
    RIGHT = 1
    DOWN = 2
    LEFT = 3


@unique
class Gender(Enum):
    """性别"""
    MALE = 1
    FEMALE = 2
    UNKNOWN = 3


@unique
class Suite(Enum):
    """花色"""
    SPADE = 0
    HEART = 1
    CLUB = 2
    DIAMOND = 3

    # 让花色可以比较
    def __lt__(self, other):
        return self.value > other.value


class Card(object):
    """一张牌"""

    def __init__(self, suite, face):
        self.suite = suite
        self.face = face

    def __str__(self):
        suites = ['♠', '♥', '♣', '♦']
        faces = ['A', '2', '3', '4', '5', '6', '7',
                 '8', '9', '10', 'J', 'Q', 'K']
        return f'{suites[self.suite.value]}{faces[self.face - 1]}'

    def __repr__(self):
        return self.__str__()


class Poker:
    """一副牌"""

    def __init__(self):
        # 通过生成式/推导式语法创建列表
        # 枚举类型本身就是可迭代的类型 - 元类提供了__iter__
        self.cards = [Card(suite, face) for suite in Suite
                      for face in range(1, 14)]
        self.index = 0

    def shuffle(self):
        """洗牌"""
        self.index = 0
        random.shuffle(self.cards)

    def deal(self):
        """发牌"""
        card = self.cards[self.index]
        self.index += 1
        return card

    @property
    def has_more(self):
        """是否有更多的牌"""
        return self.index < len(self.cards)


class Player(object):
    """玩家"""

    def __init__(self, name):
        self.name = name
        self.cards_on_hand = []

    def drop(self):
        """玩家扔掉手上的牌"""
        self.cards_on_hand.clear()

    def get_one_card(self, card):
        """玩家摸一张牌"""
        self.cards_on_hand.append(card)

    def show_cards(self):
        """获得玩家手上的牌"""
        return self.cards_on_hand

    def sort_out(self, key=lambda card: card.face, reverse=False):
        """玩家整理手上的牌"""
        self.cards_on_hand.sort(key=key, reverse=reverse)


def main():
    poker = Poker()
    poker.shuffle()
    players = [
        Player('东邪'), Player('西毒'), Player('南帝'), Player('北丐')
    ]
    for player in players:
        for _ in range(13):
            if poker.has_more:
                player.get_one_card(poker.deal())
        player.sort_out(key=lambda card: (card.suite, card.face))
        print(player.name, end=': ')
        print(player.show_cards())


if __name__ == '__main__':
    main()
